Strange return value behaviour while checking permissions of AccessRec

Hello together,

I have observed a - for me - strange and unexpected behavior while checking access records and I wonder if anybody knows the reason.

The DXL reference manual (Release 9.6.1) lists following description for checking the current permissions of an access record.


Declaration:
bool read(AccessRec ar)
bool create(AccessRec ar)
bool modify(AccessRec ar)
bool delete(AccessRec ar)
bool control(AccessRec ar)
bool write(AccessRec ar)
bool change(AccessRec ar)


Operation:
Each of the first five functions returns true if the access record confers modify, create, delete, control, or read permission.[...]

Usually I write the full query syntax (if(SomeBoolValue == true){...}), but for the functions above this seems not to work.

A little example, explaining my problem:

string GetPermissionV1(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR))          {strPermission = "R";}
  if (modify(p_oAR))        {strPermission = strPermission "M";}
  if (create(p_oAR))        {strPermission = strPermission "C";}
  if (delete(p_oAR))        {strPermission = strPermission "D";}
  if (control(p_oAR))       {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR) == true)    {strPermission = "R";}
  if (modify(p_oAR) == true)  {strPermission = strPermission "M";}
  if (create(p_oAR) == true)  {strPermission = strPermission "C";}
  if (delete(p_oAR) == true)  {strPermission = strPermission "D";}
  if (control(p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");
AccessRec ar = null;
bool      bInheritedDef = false;
isAccessInheritedDef(current Module, ad, bInheritedDef);

if (!bInheritedDef)
{
  for ar in ad do
  {
    print "V1 (" (username(ar)) "): " (GetPermissionV1(ar)) "\n";
    print "V2 (" (username(ar)) "): " (GetPermissionV2(ar)) "\n";
  }
}
else
{
  print "Access records are not available due to inherited permissions\n"
}

In my opinion both GetPermissionVx(...) functions should return the same result, but - for whatever reason - the result is:

V1 (): None
V2 (): None
V1 (AnyGroupName): RMCDA
V2 (AnyGroupName): R
V1 (AnyUsername): RMCD
V2 (AnyUsername): R

Does anybody knows the reason, why explicitly checking for "true" will cause other results?

(btw: The function V1 is returning the correct results, as configured in the clients GUI (9.6.1.8))

 

Best regards,

 

Michael


MichaelBrockhaus - Wed Dec 12 02:49:55 EST 2018

Re: Strange return value behaviour while checking permissions of AccessRec
Mathias Mamsch - Wed Dec 12 05:29:37 EST 2018

Hi Michael,

Wow. That is a tough one.

We had a similar issue with comparison in the forum once. Comparison inside expressions are not always safe, because there exists a poisionous comparison operator  bool ::==(_x,_x) which might take precedence over the comparison operator bool ::==(bool,bool) that you wanted to invoke. The problem with the create, read , modify, is, that there are a couple of perms that can cause ambiguity inside the DXL parser, especially those functions without parameters like  Permission create() or something. I really cannot find a sane reason on how the interpreter can misinterpret the statement given the existing perms (except if you may have defined custom     create/modify/control/... functions in your DXL code (which will have some bad effects on the parser!). Can you try if changing the parenthesis like this resolves the issue:

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if ((read p_oAR) == true)    {strPermission = "R";}
  if ((modify p_oAR) == true)  {strPermission = strPermission "M";}
  if ((create p_oAR) == true)  {strPermission = strPermission "C";}
  if ((delete p_oAR) == true)  {strPermission = strPermission "D";}
  if ((control p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

In DXL you should never have expressions where you call functions with single parameters like this:

myFunc (val) _operator_ somevalue

Because this leaves DXL the possibility to decide between:

myFunc (val _operator_ somevalue)
(myFunc val) _operator_ somevalue

and DXL will very much behave like in Murphys Law: If there is a way to misinterpret a statement, it will do it ;-)

I am not sure it helped, but I tried... Regards, Mathias

Re: Strange return value behaviour while checking permissions of AccessRec
MichaelBrockhaus - Wed Dec 12 06:59:39 EST 2018

Mathias Mamsch - Wed Dec 12 05:29:37 EST 2018

Hi Michael,

Wow. That is a tough one.

We had a similar issue with comparison in the forum once. Comparison inside expressions are not always safe, because there exists a poisionous comparison operator  bool ::==(_x,_x) which might take precedence over the comparison operator bool ::==(bool,bool) that you wanted to invoke. The problem with the create, read , modify, is, that there are a couple of perms that can cause ambiguity inside the DXL parser, especially those functions without parameters like  Permission create() or something. I really cannot find a sane reason on how the interpreter can misinterpret the statement given the existing perms (except if you may have defined custom     create/modify/control/... functions in your DXL code (which will have some bad effects on the parser!). Can you try if changing the parenthesis like this resolves the issue:

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if ((read p_oAR) == true)    {strPermission = "R";}
  if ((modify p_oAR) == true)  {strPermission = strPermission "M";}
  if ((create p_oAR) == true)  {strPermission = strPermission "C";}
  if ((delete p_oAR) == true)  {strPermission = strPermission "D";}
  if ((control p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

In DXL you should never have expressions where you call functions with single parameters like this:

myFunc (val) _operator_ somevalue

Because this leaves DXL the possibility to decide between:

myFunc (val _operator_ somevalue)
(myFunc val) _operator_ somevalue

and DXL will very much behave like in Murphys Law: If there is a way to misinterpret a statement, it will do it ;-)

I am not sure it helped, but I tried... Regards, Mathias

Hello Mathias,

 

thank you for your answer. Well, unfortunately the other version with additional "()" did not solve my problem. Further more I'm now a little bit more confused... Based on your guess, I've enhanced the code with four (additional) versions, you can at the bottom of this post. If you want to try, you can also run this code in the "Tools-->Edit DXL" dialog inside a module. It is a functional (minimal) working example. You just have to modify the name of the attribute in line

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");

to any existing AttrDef with specific access rights in your module.

As you can see, I've no custom defined create/modify/control functions. To be sure, I've now also started DOORS without any parameters (include scripts) and will get the same results.

Some explanations for the (four (new)) versions:

  • GetPermissionV1() and GetPermissionV2 are the original versions
  • GetPermissionV3() is your example
  • GetPermissionV4() is a try where the comparisons will be done with a previously assigned return value of each (read/modify/control) function
  • GetPermissionV5() is the same as V4 but with another sequence ("value == constant" vs. "constant == value")
  • GetPermissionV6() was a rather desperate try, also to  set the bool assignment in brackets

Well, I don't know why, but only the version V1 will work...

V1 (): None
V2 (): None
V3 (): None
V4 (): None
V5 (): None
V6 (): None
V1 (AnyGroupName): RMCDA
V2 (AnyGroupName): R
V3 (AnyGroupName): R
V4 (AnyGroupName): R
V5 (AnyGroupName): R
V6 (AnyGroupName): R
V1 (AnyUsername): RMCD
V2 (AnyUsername): R
V3 (AnyUsername): R
V4 (AnyUsername): R
V5 (AnyUsername): R
V6 (AnyUsername): R

Here is the current (minimal) working example:

string GetPermissionV1(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR))          {strPermission = "R";}
  if (modify(p_oAR))        {strPermission = strPermission "M";}
  if (create(p_oAR))        {strPermission = strPermission "C";}
  if (delete(p_oAR))        {strPermission = strPermission "D";}
  if (control(p_oAR))       {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR) == true)    {strPermission = "R";}
  if (modify(p_oAR) == true)  {strPermission = strPermission "M";}
  if (create(p_oAR) == true)  {strPermission = strPermission "C";}
  if (delete(p_oAR) == true)  {strPermission = strPermission "D";}
  if (control(p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

string GetPermissionV3(AccessRec p_oAR)
{
  string strPermission = "";
  if ((read p_oAR) == true)    {strPermission = "R";}
  if ((modify p_oAR) == true)  {strPermission = strPermission "M";}
  if ((create p_oAR) == true)  {strPermission = strPermission "C";}
  if ((delete p_oAR) == true)  {strPermission = strPermission "D";}
  if ((control p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")     {strPermission = "None";}
  return strPermission;
}

string GetPermissionV4(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (bResult == true)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (bResult == true)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (bResult == true)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (bResult == true)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (bResult == true)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV5(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (true == bResult)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV6(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = (read(p_oAR));
  if (true == bResult)      {strPermission = "R";}
  bResult = (modify(p_oAR));
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = (create(p_oAR));
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = (delete(p_oAR));
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = (control(p_oAR));
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");
AccessRec ar = null;
bool      bInheritedDef = false;
isAccessInheritedDef(current Module, ad, bInheritedDef);

if (!bInheritedDef)
{
  for ar in ad do
  {
    print "V1 (" (username(ar)) "): " (GetPermissionV1(ar)) "\n";
    print "V2 (" (username(ar)) "): " (GetPermissionV2(ar)) "\n";
    print "V3 (" (username(ar)) "): " (GetPermissionV3(ar)) "\n";
    print "V4 (" (username(ar)) "): " (GetPermissionV4(ar)) "\n";
    print "V5 (" (username(ar)) "): " (GetPermissionV5(ar)) "\n";
    print "V6 (" (username(ar)) "): " (GetPermissionV6(ar)) "\n";
  }
}
else
{
  print "Access records are not available due to inherited permissions\n"
}

Regards,

Michael

Re: Strange return value behaviour while checking permissions of AccessRec
PekkaMakinen - Wed Dec 12 07:27:22 EST 2018

MichaelBrockhaus - Wed Dec 12 06:59:39 EST 2018

Hello Mathias,

 

thank you for your answer. Well, unfortunately the other version with additional "()" did not solve my problem. Further more I'm now a little bit more confused... Based on your guess, I've enhanced the code with four (additional) versions, you can at the bottom of this post. If you want to try, you can also run this code in the "Tools-->Edit DXL" dialog inside a module. It is a functional (minimal) working example. You just have to modify the name of the attribute in line

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");

to any existing AttrDef with specific access rights in your module.

As you can see, I've no custom defined create/modify/control functions. To be sure, I've now also started DOORS without any parameters (include scripts) and will get the same results.

Some explanations for the (four (new)) versions:

  • GetPermissionV1() and GetPermissionV2 are the original versions
  • GetPermissionV3() is your example
  • GetPermissionV4() is a try where the comparisons will be done with a previously assigned return value of each (read/modify/control) function
  • GetPermissionV5() is the same as V4 but with another sequence ("value == constant" vs. "constant == value")
  • GetPermissionV6() was a rather desperate try, also to  set the bool assignment in brackets

Well, I don't know why, but only the version V1 will work...

V1 (): None
V2 (): None
V3 (): None
V4 (): None
V5 (): None
V6 (): None
V1 (AnyGroupName): RMCDA
V2 (AnyGroupName): R
V3 (AnyGroupName): R
V4 (AnyGroupName): R
V5 (AnyGroupName): R
V6 (AnyGroupName): R
V1 (AnyUsername): RMCD
V2 (AnyUsername): R
V3 (AnyUsername): R
V4 (AnyUsername): R
V5 (AnyUsername): R
V6 (AnyUsername): R

Here is the current (minimal) working example:

string GetPermissionV1(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR))          {strPermission = "R";}
  if (modify(p_oAR))        {strPermission = strPermission "M";}
  if (create(p_oAR))        {strPermission = strPermission "C";}
  if (delete(p_oAR))        {strPermission = strPermission "D";}
  if (control(p_oAR))       {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR) == true)    {strPermission = "R";}
  if (modify(p_oAR) == true)  {strPermission = strPermission "M";}
  if (create(p_oAR) == true)  {strPermission = strPermission "C";}
  if (delete(p_oAR) == true)  {strPermission = strPermission "D";}
  if (control(p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

string GetPermissionV3(AccessRec p_oAR)
{
  string strPermission = "";
  if ((read p_oAR) == true)    {strPermission = "R";}
  if ((modify p_oAR) == true)  {strPermission = strPermission "M";}
  if ((create p_oAR) == true)  {strPermission = strPermission "C";}
  if ((delete p_oAR) == true)  {strPermission = strPermission "D";}
  if ((control p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")     {strPermission = "None";}
  return strPermission;
}

string GetPermissionV4(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (bResult == true)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (bResult == true)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (bResult == true)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (bResult == true)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (bResult == true)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV5(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (true == bResult)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV6(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = (read(p_oAR));
  if (true == bResult)      {strPermission = "R";}
  bResult = (modify(p_oAR));
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = (create(p_oAR));
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = (delete(p_oAR));
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = (control(p_oAR));
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");
AccessRec ar = null;
bool      bInheritedDef = false;
isAccessInheritedDef(current Module, ad, bInheritedDef);

if (!bInheritedDef)
{
  for ar in ad do
  {
    print "V1 (" (username(ar)) "): " (GetPermissionV1(ar)) "\n";
    print "V2 (" (username(ar)) "): " (GetPermissionV2(ar)) "\n";
    print "V3 (" (username(ar)) "): " (GetPermissionV3(ar)) "\n";
    print "V4 (" (username(ar)) "): " (GetPermissionV4(ar)) "\n";
    print "V5 (" (username(ar)) "): " (GetPermissionV5(ar)) "\n";
    print "V6 (" (username(ar)) "): " (GetPermissionV6(ar)) "\n";
  }
}
else
{
  print "Access records are not available due to inherited permissions\n"
}

Regards,

Michael

Well, comparing strings works

 

string GetPermissionV7(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR) "" == "true")    {strPermission = "R";}
  if (modify(p_oAR) "" == "true")  {strPermission = strPermission "M";}
  if (create(p_oAR) "" == "true")  {strPermission = strPermission "C";}
  if (delete(p_oAR) "" == "true")  {strPermission = strPermission "D";}
  if (control(p_oAR) "" == "true") {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

 

Re: Strange return value behaviour while checking permissions of AccessRec
Mathias Mamsch - Wed Dec 12 09:33:24 EST 2018

MichaelBrockhaus - Wed Dec 12 06:59:39 EST 2018

Hello Mathias,

 

thank you for your answer. Well, unfortunately the other version with additional "()" did not solve my problem. Further more I'm now a little bit more confused... Based on your guess, I've enhanced the code with four (additional) versions, you can at the bottom of this post. If you want to try, you can also run this code in the "Tools-->Edit DXL" dialog inside a module. It is a functional (minimal) working example. You just have to modify the name of the attribute in line

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");

to any existing AttrDef with specific access rights in your module.

As you can see, I've no custom defined create/modify/control functions. To be sure, I've now also started DOORS without any parameters (include scripts) and will get the same results.

Some explanations for the (four (new)) versions:

  • GetPermissionV1() and GetPermissionV2 are the original versions
  • GetPermissionV3() is your example
  • GetPermissionV4() is a try where the comparisons will be done with a previously assigned return value of each (read/modify/control) function
  • GetPermissionV5() is the same as V4 but with another sequence ("value == constant" vs. "constant == value")
  • GetPermissionV6() was a rather desperate try, also to  set the bool assignment in brackets

Well, I don't know why, but only the version V1 will work...

V1 (): None
V2 (): None
V3 (): None
V4 (): None
V5 (): None
V6 (): None
V1 (AnyGroupName): RMCDA
V2 (AnyGroupName): R
V3 (AnyGroupName): R
V4 (AnyGroupName): R
V5 (AnyGroupName): R
V6 (AnyGroupName): R
V1 (AnyUsername): RMCD
V2 (AnyUsername): R
V3 (AnyUsername): R
V4 (AnyUsername): R
V5 (AnyUsername): R
V6 (AnyUsername): R

Here is the current (minimal) working example:

string GetPermissionV1(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR))          {strPermission = "R";}
  if (modify(p_oAR))        {strPermission = strPermission "M";}
  if (create(p_oAR))        {strPermission = strPermission "C";}
  if (delete(p_oAR))        {strPermission = strPermission "D";}
  if (control(p_oAR))       {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV2(AccessRec p_oAR)
{
  string strPermission = "";
  if (read(p_oAR) == true)    {strPermission = "R";}
  if (modify(p_oAR) == true)  {strPermission = strPermission "M";}
  if (create(p_oAR) == true)  {strPermission = strPermission "C";}
  if (delete(p_oAR) == true)  {strPermission = strPermission "D";}
  if (control(p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")    {strPermission = "None";}
  return strPermission;
}

string GetPermissionV3(AccessRec p_oAR)
{
  string strPermission = "";
  if ((read p_oAR) == true)    {strPermission = "R";}
  if ((modify p_oAR) == true)  {strPermission = strPermission "M";}
  if ((create p_oAR) == true)  {strPermission = strPermission "C";}
  if ((delete p_oAR) == true)  {strPermission = strPermission "D";}
  if ((control p_oAR) == true) {strPermission = strPermission "A";}
  if (strPermission == "")     {strPermission = "None";}
  return strPermission;
}

string GetPermissionV4(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (bResult == true)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (bResult == true)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (bResult == true)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (bResult == true)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (bResult == true)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV5(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = read(p_oAR);
  if (true == bResult)      {strPermission = "R";}
  bResult = modify(p_oAR);
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = create(p_oAR);
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = delete(p_oAR);
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = control(p_oAR);
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

string GetPermissionV6(AccessRec p_oAR)
{
  string strPermission = "";
  bool bResult = false;
  bResult = (read(p_oAR));
  if (true == bResult)      {strPermission = "R";}
  bResult = (modify(p_oAR));
  if (true == bResult)      {strPermission = strPermission "M";}
  bResult = (create(p_oAR));
  if (true == bResult)      {strPermission = strPermission "C";}
  bResult = (delete(p_oAR));
  if (true == bResult)      {strPermission = strPermission "D";}
  bResult = (control(p_oAR));
  if (true == bResult)      {strPermission = strPermission "A";}
  if (strPermission == "")  {strPermission = "None";}
  return strPermission;
}

AttrDef   ad = find(current Module, "AnyExistingAttrDefWithSpecificAccessRecords");
AccessRec ar = null;
bool      bInheritedDef = false;
isAccessInheritedDef(current Module, ad, bInheritedDef);

if (!bInheritedDef)
{
  for ar in ad do
  {
    print "V1 (" (username(ar)) "): " (GetPermissionV1(ar)) "\n";
    print "V2 (" (username(ar)) "): " (GetPermissionV2(ar)) "\n";
    print "V3 (" (username(ar)) "): " (GetPermissionV3(ar)) "\n";
    print "V4 (" (username(ar)) "): " (GetPermissionV4(ar)) "\n";
    print "V5 (" (username(ar)) "): " (GetPermissionV5(ar)) "\n";
    print "V6 (" (username(ar)) "): " (GetPermissionV6(ar)) "\n";
  }
}
else
{
  print "Access records are not available due to inherited permissions\n"
}

Regards,

Michael

Ok, it seems you found a bug here! When I put in that code:

string GetPermissionV2(AccessRec p_oAR)
{
  int x =  addr_ ((modify p_oAR) bool); 
  int y =  addr_ (true); 
  print (x "/" y "\n")

  return "XX";
}

Then I get the following output:

2/1

from the print statement which means, that the perms:

bool read (AccessRec)
bool control (AccessRec)
bool isDefault (AccessRec)
bool write (AccessRec)
bool create (AccessRec)
bool change (AccessRec)
bool partition (AccessRec)
bool modify (AccessRec)
bool delete (AccessRec)

return invalid boolean values! They seem to return not the correct boolean values (which should be 1/0) in memory. Instead they return the corresponding bit from the bitmask (which is why you get "R" everytime, because in the bitmask of the access record "R" is the first bit).

In addition the

_d ::if (bool, _d, _d)

perm evaluates the result differently than the comparison operator

. It seems that the  ::if  operator

bool ::== (bool, bool)

The if operator compares only memoryValue != 0 and the  comparison operator compares the values directly (leading to a false result in your case).

So this is a pretty serious bug, that you should report to IBM and maybe someone can retest if this bug always existed or if it was introduced with DOORS 64 ...

Regards, Mathias

 

 

Re: Strange return value behaviour while checking permissions of AccessRec
MichaelBrockhaus - Thu Dec 13 06:46:13 EST 2018

Mathias Mamsch - Wed Dec 12 09:33:24 EST 2018

Ok, it seems you found a bug here! When I put in that code:

string GetPermissionV2(AccessRec p_oAR)
{
  int x =  addr_ ((modify p_oAR) bool); 
  int y =  addr_ (true); 
  print (x "/" y "\n")

  return "XX";
}

Then I get the following output:

2/1

from the print statement which means, that the perms:

bool read (AccessRec)
bool control (AccessRec)
bool isDefault (AccessRec)
bool write (AccessRec)
bool create (AccessRec)
bool change (AccessRec)
bool partition (AccessRec)
bool modify (AccessRec)
bool delete (AccessRec)

return invalid boolean values! They seem to return not the correct boolean values (which should be 1/0) in memory. Instead they return the corresponding bit from the bitmask (which is why you get "R" everytime, because in the bitmask of the access record "R" is the first bit).

In addition the

_d ::if (bool, _d, _d)

perm evaluates the result differently than the comparison operator

. It seems that the  ::if  operator

bool ::== (bool, bool)

The if operator compares only memoryValue != 0 and the  comparison operator compares the values directly (leading to a false result in your case).

So this is a pretty serious bug, that you should report to IBM and maybe someone can retest if this bug always existed or if it was introduced with DOORS 64 ...

Regards, Mathias

 

 

Hello Mathias,

thank you again :-) I've never created an IBM ticket, but as I tried it this morning, I had to insert a customer number in the "Open a case" form...

Because of I don't know this number, I have canceled this step and contacted our IT service and asked them for contacting the IBM service...

Now I just can wait.... and use the "if(modify(AR)){}" version :-(

But thanks a lot for your investigation.

Regards,

Michael

Re: Strange return value behaviour while checking permissions of AccessRec
MichaelBrockhaus - Thu Dec 13 08:44:41 EST 2018

Mathias Mamsch - Wed Dec 12 09:33:24 EST 2018

Ok, it seems you found a bug here! When I put in that code:

string GetPermissionV2(AccessRec p_oAR)
{
  int x =  addr_ ((modify p_oAR) bool); 
  int y =  addr_ (true); 
  print (x "/" y "\n")

  return "XX";
}

Then I get the following output:

2/1

from the print statement which means, that the perms:

bool read (AccessRec)
bool control (AccessRec)
bool isDefault (AccessRec)
bool write (AccessRec)
bool create (AccessRec)
bool change (AccessRec)
bool partition (AccessRec)
bool modify (AccessRec)
bool delete (AccessRec)

return invalid boolean values! They seem to return not the correct boolean values (which should be 1/0) in memory. Instead they return the corresponding bit from the bitmask (which is why you get "R" everytime, because in the bitmask of the access record "R" is the first bit).

In addition the

_d ::if (bool, _d, _d)

perm evaluates the result differently than the comparison operator

. It seems that the  ::if  operator

bool ::== (bool, bool)

The if operator compares only memoryValue != 0 and the  comparison operator compares the values directly (leading to a false result in your case).

So this is a pretty serious bug, that you should report to IBM and maybe someone can retest if this bug always existed or if it was introduced with DOORS 64 ...

Regards, Mathias

 

 

Hello Mathias and all other guys stumbling over this issue in the future, we have received an answer (or however you want to call this) from IBM:

 

--------------------------- IBM Support ---------------------------

Clearly this is not correct.

 

Do you have a specific reason why you need to use the second form of the code?

 

The problem is not recently introduced to DOORS, it affects versions going back as far as at least v8.3.

Usually we would only raised defects against DXL if it has been recently introduced, or where there is no easy workaround.

--------------------------- IBM Support ---------------------------

 

So,... well... hm... The result seems to be: Do NOT explicitly check the return value of a bool function. Trust the internal behavior of DOORS and everything is fine.

 

Additional information (received as next - and I guess last - 'answer' from IBM):

--------------------------- IBM Support ---------------------------

The workaround is to use the first form of the code (without the "==true").

 

I appreciate that it does cause a problem when debugging. Unfortunately, since there is a solution, and since it is a very old problem, it is very unlikely to ever get fixed. As such I would not normally raise such cases as defects

--------------------------- IBM Support ---------------------------

 

Regards,

 

Michael